package shuaige.jdk.多线程.concurrent.completableFuture;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class 并行运行多个Futures示例1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        并行运行多个Futures示例1 并行运行多个Futures示例1 = new 并行运行多个Futures示例1();
        并行运行多个Futures示例1.不相同返回值();
    }

    public void 不相同返回值() throws ExecutionException, InterruptedException {
        //创建一个已经有任务结果的CompletableFuture
        CompletableFuture<String> f1 = CompletableFuture.completedFuture("return value");
        //异步处理任务,有返回值
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(this::get);
        //异步处理任务,没有返回值
        CompletableFuture<Void> f3 = CompletableFuture.runAsync(System.out::println);
        // 任意一个异步任务执行完毕,就会返回一个新的CompletableFuture
        CompletableFuture<Void> allOf = CompletableFuture.allOf(f1, f2, f3);
        allOf.join();

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        // 使用流组合结果
        List<?> collect = Stream.of(f1, f2, f3)
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    public void 相同返回值() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future1
                = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello";
        });
        CompletableFuture<String> future2
                = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Beautiful";
        });
        CompletableFuture<String> future3
                = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "World";
        });

        CompletableFuture<Void> combinedFuture
                = CompletableFuture.allOf(future1, future2, future3);
        // 阻塞并获取结果
        combinedFuture.get();
        // 直接获取结果
        System.out.println(future3.get());
        System.out.println(future2.get());
        System.out.println(future1.get());

        // 使用流组合结果
        String combined = Stream.of(future1, future2, future3)
                .map(CompletableFuture::join)
                .collect(Collectors.joining(" "));
        System.out.println(combined);
    }

    public String get() {
        delay();
        return "异步任务结果";
    }

    public void delay() {
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
